﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Security.Cryptography;
using CPPaquetes.BusinessEntities.Integration;
using System.IO;
using System.Xml.Serialization;
using CPPaquetes.Infraestructure.Logging;
using System.Xml;
using System.Runtime.Serialization;

namespace CPPaquetes.Integracion
{
    public class DispatcherHandler
    {

        #region "DATAVIA 2.0"

        public Dispatcher.Service.Session sessionData()
        {

            Dispatcher.Service.Session session = new Dispatcher.Service.Session();

            session.CodigoAcceso = ConfigurationManager.AppSettings.Get("DataViaCodigoAcceso");
            string seed = null;
            session.Password = EncodePassword(ConfigurationManager.AppSettings.Get("DataViaPassword"), ref seed);
            session.Seed = seed;
            session.Type = Dispatcher.Service.SessionLogType.Authenticate;
            return session;
        }

        public string EncodePassword(string password, ref string seed)
        {
            seed = GetSeed().ToString();
            password = GetMD5Hash(password.ToUpper());
            string encodedPassword = GetMD5Hash(password.ToUpper().Trim() + seed.Trim());
            return encodedPassword;
        }

        private int GetSeed()
        {
            Random rdm = new Random();
            return rdm.Next();
        }

        private string GetMD5Hash(string input)
        {
            try
            {
                MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
                StringBuilder sBuilder = new StringBuilder();
                Int32 i = default(Int32);
                Byte[] data = md5Hasher.ComputeHash(System.Text.Encoding.Default.GetBytes(input));
                //Convierte el texto en un array de bytes.
                for (i = 0; i <= data.Length - 1; i++)
                {
                    sBuilder.Append(data[i].ToString("x2"));
                }
                return sBuilder.ToString();
            }
            catch
            {
                return "";
            }
        }

        public DispatcherResponse sendOne(int ida, object item)
        {

            DispatcherResponse disResponse = new DispatcherResponse();

            Dispatcher.Service.Service service = new Dispatcher.Service.Service();
            service.Url = ConfigurationManager.AppSettings.Get("Dispatcher.Service");

            try
            {
                Dispatcher.Service.Request request = new Dispatcher.Service.Request();

                request.Session = sessionData();

                if (ida > 0 && (item != null))
                {
                    request.Processes = new Dispatcher.Service.Process[1];
                    request.Processes[0] = new Dispatcher.Service.Process();
                    request.Processes[0].Ida = ida;
                    request.Processes[0].Item = item;
                }
                service.Timeout = 1000 * 60;
                                
                Dispatcher.Service.Response response = service.Execute(request);

                if (!response.Success)
                {                   
                    LogManager.Instance().Info(SerializeToString<Dispatcher.Service.Request>(request));
                    LogManager.Instance().Info(SerializeToString<Dispatcher.Service.Response>(response));
                    if (response.Errors.Length > 0)
                    {
                        disResponse.Error = response.Errors[0].Description;
                    }
                    else
                    {
                        disResponse.Error = "response.Success = " + response.Success.ToString();
                    }
                }
                else
                {
                    if ((response.Processes != null) && response.Processes.Length > 0)
                    {
                        disResponse.RollBack = response.Processes[0].Rollback;
                        disResponse.Status = response.Processes[0].Status;
                        disResponse.Response = response.Processes[0].Item;
                    }
                    else
                    {
                        disResponse.Error = "response.Processes is empty.";
                    }

                    LogManager.Instance().Debug(SerializeToString<Dispatcher.Service.Request>(request));
                }
            }
            catch (Exception ex)
            {

                service.Dispose();
                throw ex;
            }

            return disResponse;

        }
        #endregion

        public static void SerializeToXML<T>(T t, String inFilename)
        {
            string XMLPath = AppDomain.CurrentDomain.BaseDirectory + @"XML\"+ inFilename;

            if (!Directory.Exists(AppDomain.CurrentDomain.BaseDirectory + @"XML\" ))
                Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory + @"XML\");

            XmlSerializer serializer = new XmlSerializer(t.GetType());
            TextWriter textWriter = new StreamWriter(XMLPath);
            serializer.Serialize(textWriter, t);
            textWriter.Close();
        }

        public static string SerializeToString<T>(T from)
        {
            try
            {
                using (var ms = new MemoryStream())
                {
                    using (var xw = new XmlTextWriter(ms, Encoding.UTF8))
                    {
                        if (false)
                        {
                            xw.Formatting = Formatting.Indented;
                        }

                        XmlSerializer serializer = new XmlSerializer(from.GetType());
                        serializer.Serialize(xw, from);
                        xw.Flush();
                        ms.Seek(0, SeekOrigin.Begin);
                        using (var reader = new StreamReader(ms))
                        {
                            return reader.ReadToEnd();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw new SerializationException(string.Format("Error serializing object of type {0}", from.GetType().FullName), ex);
            }
        }

        public int CrearNegocio(int IdSucursal, int IdVendedor, int IdCanal, string NombreCotiza, string Telefono, string Email, string Moneda, string DescripcionServicio, int IdPrograma, DateTime FechaIn, int Monto)
        {

            Dispatcher.Service.Negocio negocio = new Dispatcher.Service.Negocio();
            negocio.Numero = 0;
            //negocio.IdCanal = Convert.ToInt16(ConfigurationManager.AppSettings.Get("IdCanal"));
            //Se modifica por el canal del usuario
            negocio.IdCanal = (short)IdCanal;
            negocio.IdTipoNegocio = Convert.ToInt16(ConfigurationManager.AppSettings.Get("IdTipoNegocio"));
            //negocio.IdSucursal = Convert.ToInt32(ConfigurationManager.AppSettings.Get("IdSucursal"));
            negocio.IdSucursal = IdSucursal;
            negocio.IdVendedor = IdVendedor;
            negocio.Moneda = Moneda;
            negocio.CantidadPax = 1;
            //negocio.Referente = Vendedor;
            negocio.Referente = NombreCotiza; //Se modifica por el nombre de quien compra
            negocio.Telefono = Telefono;
            negocio.Email = Email;
            negocio.AltaNegocio = DateTime.Now;

            DispatcherHandler dispatcher = new DispatcherHandler();
            DispatcherResponse response = dispatcher.sendOne(18, negocio);

            if (!string.IsNullOrEmpty(response.Error))
            {                
                throw new Exception(response.Error);
            }   
            negocio = (Dispatcher.Service.Negocio)response.Response;


            if (!response.Status)
            {
                return 0;
            }
            else
            {
                negocio.Numero = negocio.Numero;
                try
                {
                    CrearServicio(negocio.Numero, DescripcionServicio, negocio, IdPrograma, FechaIn, Monto);
                }
                catch
                {
                    
                }
                return negocio.Numero;
            }
        }

        public int CrearServicio(int NumeroNegocio, string DescripcionServicio, Dispatcher.Service.Negocio negocio, int IdPrograma, DateTime FechaIn, int Monto)
        {

            CPPaquetes.Integracion.Dispatcher.Service.Varios servicio = new CPPaquetes.Integracion.Dispatcher.Service.Varios();
            
            servicio = new Dispatcher.Service.Varios();

            servicio.IdServicio = 0;
            servicio.StatusFecha = DateTime.Now;
            servicio.TipoServicio = "V"; // Varios
            servicio.IdTipoNegocio = 1;
            servicio.DescripcionServicio = DescripcionServicio;
            servicio.Programa = 0;
            //servicio.Vencimiento = DateTime.Now.AddDays(1);
            servicio.Negocio = NumeroNegocio;
            servicio.IdCanal = negocio.IdCanal;
            servicio.IdTarifario = " ";
            servicio.IdSucursal = negocio.IdSucursal;
            servicio.Moneda = negocio.Moneda;
            servicio.Adult = 1;
            servicio.Vendedor = negocio.IdVendedor.ToString();
            
            //Valores de Prueba
            servicio.FechaIn = FechaIn;
            servicio.FechaOut = FechaIn;
            servicio.VentaReferencia = Monto;

            //servicio.FechaIn = DateTime.Now;
            //servicio.FechaOut = DateTime.Now;
            
            //servicio.Vencimiento = DateTime.Now;
            servicio.IdDestino = ConfigurationManager.AppSettings["IdDestinoServicioPreventa"].ToString();
            servicio.IdCategoria = short.Parse(ConfigurationManager.AppSettings["IdCategoriaServicioPreventa"].ToString());
            //servicio.IdCategoria = 11;
            servicio.IdStatusSign = negocio.IdVendedor;
            servicio.Descripcion = DescripcionServicio;
            servicio.Observaciones = ConfigurationManager.AppSettings["LinkPrograma"].ToString() + IdPrograma.ToString();
            //servicio.Pasajeros = new Dispatcher.Service.ServicioPasajero[1];

            //servicio.Pasajeros[0] = new Dispatcher.Service.ServicioPasajero();

            //servicio.Pasajeros[0].IdPasajero = 72;
            //servicio.Pasajeros[0].IdTipo = 1;
            //servicio.Pasajeros[0].TipoPax = "A";

            
            DispatcherHandler dispatcher = new DispatcherHandler();
            DispatcherResponse response = dispatcher.sendOne(74, servicio);

            if (!string.IsNullOrEmpty(response.Error))
            {
                throw new Exception(response.Error);
            }
            negocio = (Dispatcher.Service.Negocio)response.Response;

            if (!response.Status)
            {
                return 0;
            }
            else
                return negocio.Numero;
        }
    }
}
